package what.api;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.JavaClass;

public class NewApi {

	public static void main(String[] args) throws Exception {
		if (args.length != 2) {
			System.out
					.println("Argument: <product's top path> <full resulting log file>");
			return;
		}
		File source = new File(args[0]);
		File log = new File(args[1]);
		BufferedWriter result = new BufferedWriter(new FileWriter(log));
		NewApi newApi = new NewApi();
		newApi.parse(source, result);
		result.close();
	}

	public static void parse(File source, BufferedWriter result)
			throws IOException {
		if (source.isFile()) {
			parseFile(source, result);
			return;
		}
		if (source.isDirectory()) {
			System.out.println("Parsing " + source);
			for (File child : source.listFiles())
				parse(child, result);
		}
	}

	public static void parseFile(File source, BufferedWriter result)
			throws IOException {
		if (source.getName().endsWith(".class")) {
			ClassParser cp = new ClassParser(source.getCanonicalPath());
			log(cp.parse(), result);
			return;
		}
		if (source.getName().endsWith(".jar")
				|| source.getName().endsWith(".zip")) {
			parseJar(source, result);
		}
	}

	public static void parseJar(File source, BufferedWriter result)
			throws IOException {
		ZipInputStream stream = new ZipInputStream(new BufferedInputStream(
				new FileInputStream(source)));
		ZipEntry entry = stream.getNextEntry();
		while (entry != null) {
			String name = entry.getName();
			if (name.endsWith(".class")) {
				ClassParser cp = new ClassParser(source.getCanonicalPath(),
						name);
				log(cp.parse(), result);
			}
			entry = stream.getNextEntry();
		}

	}

	/**
	 * Format: package name | class name | public method1{signature}public
	 * method2{}...
	 */
	public static void log(JavaClass javaClass, BufferedWriter result)
			throws IOException {
		String string = ApiClass.save(javaClass);
		if (string != null) {
			result.append(string);
		}

	}

	public static ApiLog createApiLog(File source) throws IOException {
		BufferedReader br = new BufferedReader(new FileReader(source));
		ApiLog result = new ApiLog(source.getName());
		while (true) {
			String line = br.readLine();
			if (line == null)
				break;
			ApiClass.load(line, result);
		}
		return result;
	}
}
